import { BufferTargetType, BufferUsage } from "../../../RenderEngine/RenderEnum/BufferTargetType";
import { DrawType } from "../../../RenderEngine/RenderEnum/DrawType";
import { MeshTopology } from "../../../RenderEngine/RenderEnum/RenderPologyMode";
import { Shader3D, ShaderFeatureType } from "../../../RenderEngine/RenderShader/Shader3D";
import { SubShader } from "../../../RenderEngine/RenderShader/SubShader";
import { VertexDeclaration } from "../../../RenderEngine/VertexDeclaration";
import { LayaGL } from "../../../layagl/LayaGL";
import { Color } from "../../../maths/Color";
import { Vector3 } from "../../../maths/Vector3";
import { VertexElement } from "../../../renders/VertexElement";
import { VertexElementFormat } from "../../../renders/VertexElementFormat";
import { FastSinglelist } from "../../../utils/SingletonList";
import { IRenderContext2D } from "../../DriverDesign/2DRenderPass/IRenderContext2D";
import { IRenderCMD } from "../../DriverDesign/RenderDevice/IRenderCMD";
import { ShaderData, ShaderDataType } from "../../DriverDesign/RenderDevice/ShaderData";
import { RenderState } from "../../RenderModuleData/Design/RenderState";
import { GLESInternalRT } from "../RenderDevice/GLESInternalRT";
import { GLESRenderGeometryElement } from "../RenderDevice/GLESRenderGeometryElement";
import { GLESShaderData } from "../RenderDevice/GLESShaderData";
import { GLESVertexBuffer } from "../RenderDevice/GLESVertexBuffer";
import { GLESRenderElement2D } from "./GLESRenderElement2D";

export class GLESRenderContext2D implements IRenderContext2D {

    static isCreateBlitScreenELement = false;

    static blitScreenElement: GLESRenderElement2D;

    private _tempList: any = [];

    /**
     * @internal
     */
    _nativeObj: any;

    private _dist: GLESInternalRT;

    public get invertY(): boolean {
        return this._nativeObj.invertY;
    }

    public set invertY(value: boolean) {
        this._nativeObj.invertY = value;
    }

    public get pipelineMode(): string {
        return this._nativeObj.pipelineMode;
    }

    public set pipelineMode(value: string) {
        this._nativeObj.pipelineMode = value;
    }

    constructor() {
        this._nativeObj = new (window as any).conchGLESRenderContext2D();
        this._nativeObj.setGlobalConfigShaderData((Shader3D._configDefineValues as any)._nativeObj);
        this._nativeObj.pipelineMode = "Forward";
    }

    private _passData: GLESShaderData = null;
    private _passDataShell: GLESShaderData = new GLESShaderData(null, false);
    public get passData(): GLESShaderData {
        this._passDataShell._nativeObj = this._nativeObj.passData;
        return this._passDataShell;
    }
    public set passData(value: GLESShaderData) {
        this._passData = value;
        this._nativeObj.passData = value ? value._nativeObj : null;
    }


    drawRenderElementList(list: FastSinglelist<GLESRenderElement2D>): number {
        this._tempList.length = 0;
        let listelement = list.elements;
        listelement.forEach((element) => {
            this._tempList.push(element._nativeObj);
        });
        return this._nativeObj.drawRenderElementList(this._tempList, list.length);
    }

    setRenderTarget(value: GLESInternalRT, clear: boolean, clearColor: Color): void {
        this._dist = value;
        this._nativeObj.setRenderTarget(value ? value._nativeObj : null, clear, clearColor);
    }

    getRenderTarget(): GLESInternalRT {
        return this._dist;
    }

    setOffscreenView(width: number, height: number): void {
        this._nativeObj.setOffscreenView(width, height);
    }

    drawRenderElementOne(node: GLESRenderElement2D): void {
        this._nativeObj.drawRenderElementOne(node._nativeObj);
    }

    runOneCMD(cmd: IRenderCMD): void {
        this._nativeObj.runOneCMD((cmd as any)._nativeObj);
    }

    runCMDList(cmds: IRenderCMD[]): void {
        let nativeobCMDs: any[] = [];
        cmds.forEach(element => {
            nativeobCMDs.push((element as any)._nativeObj);
        });

        this._nativeObj.runCMDList(nativeobCMDs);
    }





}